/*
 *     This file is part of Neptune Network Emulator.
 *
 *  Neptune Network Emulator is free software: 
 *  you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  Neptune Network Emulator is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Neptune Network Emulator.  If not, see <http://www.gnu.org/licenses/>.
 *
 */
/**
 *
 */
package neptune.web.client.view.components.dialogs;

import neptune.web.client.WebInterface;
import neptune.web.client.services.experiment.ExperimentService;
import neptune.web.client.view.components.MessageWidget;

import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.*;


/**
 * @author Luigi Lorenzo Arpino [luigiarpino@yahoo.it]
 *
 */
public class LinKernighanAllocatorDialog extends DialogBox implements ClickListener 
{
	
	private ListBox listBoxNumeroNodi;
	private ListBox listBoxMaxLinkBandwidth;
	private CheckBox checkBoxSharing;
	private String experimentId;
	
	

	public LinKernighanAllocatorDialog(String experimentId)
	{
		super(false, true);
		this.experimentId=experimentId;
		FlexTable mainPanel = new FlexTable();
		mainPanel.setWidth("95%");
		ScrollPanel mainPanelWrapper = new ScrollPanel(mainPanel);
		mainPanelWrapper.setHeight("350px");

		/*
		 * Inizio costruzione campi per inserimemnto dati
		 */
		// HELP
		HTML help1 = new HTML("<b>Max Vms per node</b>: the numbers of max virtual machines than can runs on a physical machine");
		help1.addStyleName("LinkPropsDialog-help");
		mainPanel.setWidget(0, 0, help1);
		mainPanel.getFlexCellFormatter().setColSpan(0, 0, 2);
		
		
		// Numero Nodi
		Label labelName = new Label("Max VMs per node");
		labelName.addStyleName("NodePropsDialog-label");
		this.listBoxNumeroNodi = new ListBox();
		this.listBoxNumeroNodi.addStyleName("NodePropsDialog-input");
		for(int i=0; i<20 ; i++)
		{
			this.listBoxNumeroNodi.addItem(String.valueOf(i+1));
		}
		//this.textNamePhysicalMachine.addStyleName("NodePropsDialog-input");
		mainPanel.setWidget(1, 0, labelName);
		mainPanel.setWidget(1, 1, this.listBoxNumeroNodi);
		
		// HELP
		HTML help2 = new HTML("<b>Max link bandwidth</b>: the max physical link bandwidth");
		help2.addStyleName("LinkPropsDialog-help");
		mainPanel.setWidget(2, 0, help2);
		mainPanel.getFlexCellFormatter().setColSpan(2, 0, 2);
		
		// Bandwidth
		Label labelDescription = new Label("Max link bandwidth");
		labelDescription.addStyleName("NodePropsDialog-label");
		this.listBoxMaxLinkBandwidth = new ListBox();
		this.listBoxMaxLinkBandwidth.addStyleName("NodePropsDialog-input");
		this.listBoxMaxLinkBandwidth.addItem("10 Mbps");
		this.listBoxMaxLinkBandwidth.addItem("100 Mbps");
		this.listBoxMaxLinkBandwidth.addItem("1000 Mbps");
		this.listBoxMaxLinkBandwidth.setSelectedIndex(1);
		mainPanel.setWidget(3, 0, labelDescription);
		mainPanel.setWidget(3, 1, this.listBoxMaxLinkBandwidth);
		
		// HELP
		HTML help3 = new HTML("<b>Enable sharing</b>: Enable sharing of physical machines between more experiments.");
		help3.addStyleName("LinkPropsDialog-help");
		mainPanel.setWidget(4, 0, help3);
		mainPanel.getFlexCellFormatter().setColSpan(4, 0, 2);
		
		//Optimize Mapping process
		Label labelSharing=new Label("Enable sharing" );
		labelSharing.addStyleName("NodePropsDialog-label");
		this.checkBoxSharing=new CheckBox();
		mainPanel.setWidget(5, 0, labelSharing);
		mainPanel.setWidget(5, 1, checkBoxSharing);
		
		// HELP
		HTML help4 = new HTML("<br><br><img src='img/info.jpg' align='left'/> Click <a href='infoAllocation.html' target='blank'> here</a> to get more info about allocation process");
		help4.addStyleName("LinkPropsDialog-help");
		mainPanel.setWidget(6, 0, help4);
		mainPanel.getFlexCellFormatter().setColSpan(6, 0, 2);
		

		
		// BUTTON PANEL
		HorizontalPanel buttonPanel = new HorizontalPanel();
		Button ok = new Button("Allocate");
		ok.addClickListener(this);
		ok.addStyleName("NodePropsDialog-button");
		Button cancel = new Button("Cancel");
		cancel.addClickListener(this);
		cancel.addStyleName("NodePropsDialog-button");
		buttonPanel.add(ok);
		buttonPanel.add(cancel);

		VerticalPanel vPanel = new VerticalPanel();
		vPanel.setWidth("100%");
		vPanel.add(mainPanelWrapper);
		vPanel.add(buttonPanel);
		vPanel.setCellHorizontalAlignment(buttonPanel, VerticalPanel.ALIGN_RIGHT);

		this.setWidget(vPanel);
		this.setText("Topology Mapping");

		// Styles
		mainPanelWrapper.addStyleName("NodePropsDialog-mainWrapper");
		mainPanel.addStyleName("NodePropsDialog-mainPanel");
		this.addStyleName("NodePropsDialog");
	}
	
	/* (non-Javadoc)
	 * @see com.google.gwt.user.client.ui.ClickListener#onClick(com.google.gwt.user.client.ui.Widget)
	 */
	public void onClick(Widget sender)
	{
		if( ((Button) sender).getText().equals("Allocate") )
		{
			String expId=this.experimentId;
			int maxVMsPerNode = this.listBoxNumeroNodi.getSelectedIndex()+1;
			int maxBandwidth=0;
			int index = this.listBoxMaxLinkBandwidth.getSelectedIndex();
			if (index==0)
			{
				maxBandwidth=10;
			}
			else if(index==1)
			{
				maxBandwidth=100;
			}
			else if(index==2)
			{
				maxBandwidth=1000;
			}
			else
			{
				maxBandwidth=0;
			}
			final PopupPanel popup = WebInterface.showMessageDialog(
					new MessageWidget(MessageWidget.LOADING,
							"Sending allocation request..."), false);
			if (this.checkBoxSharing.isChecked())
			{
				// Allocazione con ottimizzazione
				ExperimentService.Util.getInstance().allocateExperimentWithLinKernighanSharing(expId, maxVMsPerNode, maxBandwidth,new AsyncCallback<String>()
				{
					public void onFailure(Throwable caught) 
					{
						popup.hide();
						String message = "Impossible to send experiment '"
								+ experimentId
								+ "' allocation request. Cause:\n"
								+ caught.getMessage();
						WebInterface.addMessageToConsoleAndShowDialog(
								message, true);
					}

					public void onSuccess(String result) 
					{
						popup.hide();
						//setExperimentState(result);
						String message = "Experiment '"	
							+  experimentId
							+ "' allocation request sent.\n";
						WebInterface.addMessageToConsoleAndShowDialog(
								message+result, false);
					}
				});
			}
			else
			{
				// Allocazione senza ottimizzazione
				ExperimentService.Util.getInstance().allocateExperimentWithLinKernighan(expId, maxVMsPerNode, maxBandwidth,new AsyncCallback<String>()
				{
					public void onFailure(Throwable caught) 
					{
						popup.hide();
						String message = "Impossible to send experiment '"
								+ experimentId
								+ "' allocation request. Cause:\n"
								+ caught.getMessage();
						WebInterface.addMessageToConsoleAndShowDialog(
								message, true);
					}

					public void onSuccess(String result) 
					{
						popup.hide();
						//setExperimentState(result);
						String message = "Experiment '"	
							+  experimentId
							+ "' allocation request sent.\n";
						WebInterface.addMessageToConsoleAndShowDialog(
								message+result, false);
					}
				});
			}
			
			this.hide();
		}
		else if ( ((Button) sender).getText().equals("Cancel") )
		{
			this.hide();
		}
		else
		{
			
		}
	}

}
